package com.encrypt.classloader;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;

import javax.crypto.Cipher;

/**
 * 密钥型类加载器（目录）
 * 
 * @author yiyongpeng
 * 
 */
public class FileSystemDecryptClassLoader extends AbstractDecryptClassLoader {
	@Override
	public URL findResource(String name) {
		File file = new File(classpath.concat(File.separator).concat(name));
		return getURL(file);
	}

	@Override
	protected byte[] loadFileData(String name) {
		name = classpath.concat(File.separator).concat(name);
		BufferedInputStream in = null;
		try {
			File file = new File(name);
			if (!file.exists())
				return null;
			in = new BufferedInputStream(new FileInputStream(file));
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			byte[] buf = new byte[1024];
			for (int size; (size = in.read(buf)) > 0;)
				out.write(buf, 0, size);
			return out.toByteArray();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}

	/**
	 * 如果没有指定私钥文件，默认使用后缀名为“.key”的同名文件作为私钥
	 * 
	 * @param privateKeyUrl
	 * @param classPath
	 * @return
	 */
	private static URL getPrivateKeyUrl(URL privateKeyUrl, String classPath) {
		if (privateKeyUrl != null)
			return privateKeyUrl;
		classPath = classPath.concat(".key");
		return getURL(new File(classPath));
	}

	/**
	 * 如果没有指定公钥文件，默认使用后缀名为“.cert”的同名文件作为公钥
	 * 
	 * @param publicKeyUrl
	 * @param classPath
	 * @return
	 */
	private static URL getPublicKeyUrl(URL publicKeyUrl, String classPath) {
		if (publicKeyUrl != null)
			return publicKeyUrl;
		classPath = classPath.concat(".cert");
		return getURL(new File(classPath));
	}

	public FileSystemDecryptClassLoader(String classPath) {
		this(classPath, null, null);
	}

	/**
	 * 
	 * @param classPath
	 *            Zip文件名
	 * @param publicKeyUrl
	 *            公钥文件名
	 * @param privateKeyUrl
	 *            私钥文件名
	 * @throws IOException
	 */
	public FileSystemDecryptClassLoader(String classPath, URL publicKeyUrl,
			URL privateKeyUrl) {
		this(classPath, getCipher(getPublicKeyUrl(publicKeyUrl, classPath),
				getPrivateKeyUrl(privateKeyUrl, classPath)));
	}

	public FileSystemDecryptClassLoader(String classPath, Cipher cipher) {
		super(cipher);
		this.classpath = classPath;
	}

	private String classpath;
}
